<template>
  <div style="display: flex; height: 100%; flex: 1;">
    <HierarchyList :pagination="pagination" :columns="columns" :load-data="loadData"
                   ref="refHiRole" :search-form="searchForms" :create-label="addRoleLabel"
                   :export-label="exportLabel" :export-asset="exportRoles"
                   :import-label="importLabel" :import-asset="importRoles"
                   :filter-action="true" :filter-data="filterData"
                   :add-item="addRole" :hidePageable="true"/>
    <EditDialog ref="refEditDlg" :columns="columns" :rules="rules" :submit="onSubmit"
                :form-label-width="100" :is-show-dialog="false"/>
    <ImportDataDialog ref="refImport" url="/uni-center/v1/excel/asset/import/type"
                      :tips="'是否更新已经存在的角色数据'" :do-upload="uploadAction"/>
  </div>
</template>

<script setup lang="ts">

import {computed, getCurrentInstance, reactive, ref} from "vue";
import {currentNames, TYPES} from "@/stores/conf";
import {loadAssetLevel} from "@/apis/sop";
import {requestForm} from "@/apis/request";
import HierarchyList from "@/views/sop/list/HierarchyList.vue";
import {msgError, msgInfo, showInfo} from "@/utils/InfoUtil";
import EditDialog from "@/components/common/EditDialog.vue";
import {computeTreeData} from "@/utils/DataTreeUtil";
import {buildAsset} from "@/utils/sop/DataUtil";
import {useCurrent} from "@/utils/sop/UseCurrentFunc";
import {
  exportAssetByType,
  filterTreeList,
  getStateOptions,
  getStateTag,
  getStateText,
  handleLevelData
} from "@/utils/SystemUtil";
import {useStore} from "@/stores";
import {useAssetOp} from "@/utils/sop/UseAssetOp";
import ImportDataDialog from "@/widget/ImportDataDialog.vue";
import {hasMenuPermit} from "@/utils/sop/PermitUtil";
import {refreshUserAssets} from "@/utils/sop/RoleUtil";
import {filterNameInput} from "@/utils/StrUtil";

const props = withDefaults(defineProps<{
  entry: any,
}>(), {});

const store = useStore();
const refHiRole = ref();
const refEditDlg = ref();
const refImport = ref();
const currentItem = ref<any>();
const roleData = ref([]);

const {proxy} = getCurrentInstance();

const {updateCurrent, current} = useCurrent(currentNames.ROLE);
const {doSaveAsset, doDeleteAsset} = useAssetOp(props.entry);

const rules = reactive({
  name: [{required: true, message: '请输入角色名称', trigger: ['blur']},],
})

const addRoleLabel = computed(() => {
  return hasMenuPermit('asset:role:add') ? '新增角色' : '';
})

const importLabel = computed(() => {
  return hasMenuPermit('asset:role:import') ? '导入' : '';
})

const exportLabel = computed(() => {
  return hasMenuPermit('asset:role:export') ? '导出' : '';
})

const importRoles = () => {
  refImport.value.handleImport();
}

const exportRoles = async () => {
  const platform: any = store.getCurrentPlatform();

  await exportAssetByType({
    platformId: platform.id,
    assetType: TYPES.ROLE
  }, `${TYPES.ROLE}_${new Date().getTime()}.xlsx`, {});
}

const getSearchItems = () => {
  const searchItems = [];
  searchItems.push({
    type: 'input',
    name: 'name',
    label: `角色名称`,
    size: 'default',
    placeholder: `请输入角色名称`,
    clearable: true,
    defValue: '',
    width: '200px',
  });

  return searchItems;
}

const searchForms = ref(getSearchItems());

const filterData = async (data: any, params: string) => {
  if (!params || !params.name) {
    return data;
  }
  return filterTreeList(data, (item: any) => {
    return item.name.indexOf(params.name) != -1 ? 1 : 2;
  });
}

const uploadAction = async (option: any, url: any, headers: any) => {
  const platform: any = store.getCurrentPlatform();
  let formData: any = new FormData();
  formData.append("file", option.file);
  formData.append("assetType", TYPES.ROLE);
  formData.append("platformId", platform.id);

  await requestForm({
    url: url,
    method: 'post',
    headers: headers,
    data: formData,
  });

  setTimeout(async () => {
    await refreshUserMenus();
    refHiRole.value?.refresh()
  },300);
}

const loadData = async (params: any) => {
  const platform: any = store.getCurrentPlatform();

  const result = await loadAssetLevel({
    server: props.entry.server,
    targetId: platform.id,
    assetType: TYPES.ROLE,
    ...params,
  });

  if (result && result.data) {
    roleData.value = [];
    handleLevelData(roleData.value, result.data, []);
    delete result.data;
    result.data = {};
    result.data.data = roleData.value;
  } else {
    roleData.value = [];
  }

  return result;
}

const onSubmit = async (item: Record<string, any>) => {
  const platform: any = store.getCurrentPlatform();
  let assetInfo = buildAsset(item, 'ROLE', {
    $comment: item.$comment || ''
  });

  assetInfo.classify = "ROLE_TREE";

  const result = await doSaveAsset(platform.id, assetInfo);
  if (result && result.code === 0) {
    msgInfo('保存角色信息成功!');
    setTimeout(async () => {
      await refreshUserMenus();
      refHiRole.value?.refresh();
    }, 300);
  } else {
    msgError(result ? result.message : '保存角色信息失败！');
  }

  return result;
}

const newRole = () => {
  return {
    state: 1,
    type: TYPES.ROLE,
  };
}

const pagination = ref({
  current: 1,
  pageSize: 20,
  total: 0,
});

const getTargetId = () => {
  return '';
}

const refreshUserMenus = async () => {
  if (await refreshUserAssets(currentNames.PLAT_USER)) {
    proxy.$bus.emit('roleChanged');
  }
}

const buildRoleOperations = (row: any) => {
  const operations: any = [];

  operations.push({
    name: '新增',
    disabled: (row: any) => {
      return row.noAuth == 1 || !hasMenuPermit('asset:role:add');
    },
    callback: (data: any, row: any) => {
      const parent = row;
      currentItem.value = newRole();
      currentItem.value.disabled = true;
      currentItem.value.parentId = parent.id;
      currentItem.value.treeData = [{
        value: parent.id,
        label: parent.name,
      }]
      refEditDlg.value?.editAdd('新增角色', currentItem.value);
    }
  });
  operations.push({
    name: '编辑',
    iconType: 'primary',
    disabled: (row: any) => {
      return row.noAuth == 1 || !hasMenuPermit('asset:role:edit');
    },
    callback: (data: any, row: any) => {
      const treeData = computeTreeData(data, row);
      currentItem.value = row;
      currentItem.value.treeData = treeData.data;
      refEditDlg.value?.editUpdate('编辑角色', row);
    }
  });
  operations.push({
    type: 'confirm',
    name: '删除',
    disabled: (row: any) => {
      return row.noAuth == 1 || !hasMenuPermit('asset:role:delete');
    },
    confirm: async (data: any, row: any) => {
      if (row.children && row.children.length != 0) {
        showInfo('请先删除角色子角色！');
      } else {
        const result = await doDeleteAsset(getTargetId(), row);
        if (result.code === 0) {
          msgInfo('删除角色成功！');
          setTimeout(async () => {
            await refreshUserMenus();
            refHiRole.value?.refresh();
          }, 300);
        } else {
          msgError(result.message ? result.message : '删除角色失败！');
        }
      }
    }
  });
  return operations;
}

const columns = ref([
  {
    id: 'id',
    name: '标识',
    hideCol: true,
    show: false,
    canEdit: false,
  },
  {
    id: 'parentId',
    name: '父角色',
    type: 'tree',
    show: false,
    hideCol: true,
    canEdit: true,
    readOnly: true,
    treeKey: 'parentName'
  },
  {
    id: 'name',
    name: '角色名称',
    show: true,
    offset: '16px',
    align: 'left',
    headAlign: 'left',
    canAction: (row: any) => {
      return row.noAuth != 1;
    },
    action: (data: any, row: any) => {
      updateCurrent({type: TYPES.ROLE, ...row});
    }
  },
  {
    id: 'code',
    name: '角色码',
    show: true,
    inputCheck: (row: any) => {
      row.code = filterNameInput(row.code);
      if (row.code.length > 31) {
        row.code = row.code.substring(0, 31);
      }
    }
  },
  {
    id: 'state',
    name: '状态',
    show: true,
    tag: 'true',
    type: 'select',
    tagType: (tag: number) => {
      return getStateTag(tag);
    },
    tagText: (tag: number) => {
      return getStateText(tag);
    },
    options: getStateOptions()
  },
  {
    id: '$comment',
    name: '描述',
    show: true,
  },
  {
    id: 'createTime',
    name: '创建时间',
    show: true,
    canEdit: false,
  },
  {
    id: 'operation',
    name: '操作',
    show: true,
    hideCol: true,
    canEdit: false,
    fixed: 'right',
    buildOperations: (row: any) => {
      return buildRoleOperations(row);
    },
  }
]);

const addRole = () => {
  currentItem.value = newRole();
  currentItem.value.parentId = current().id;
  refEditDlg.value?.editAdd('新增角色', currentItem.value);
}

const refresh = () => {
  refHiRole.value?.refresh();
}

defineExpose({
  refresh,
})

</script>

<style scoped>
.el-form-item-class .el-form-item__label {
  font-size: 12px;
}

</style>
